using System;
using System.ComponentModel;
using System.Diagnostics;
using ZoneFiveSoftware.Common.Data;
using ZoneFiveSoftware.Common.Data.Fitness;
using ZoneFiveSoftware.Common.Visuals;
using FilteredStatistics.Common;
using FilteredStatistics.Controller;
using FilteredStatistics.View;

namespace FilteredStatistics.Data
{
    class RecordedLapNamedZone : INamedZone
    {
        public RecordedLapNamedZone(IActivity activity, int lapIndex)
        {
            Debug.Assert(activity != null);

            ActivityInfo activityInfo = ActivityInfoCache.Instance.GetInfo(activity);

            m_Activity = activity;
            m_ActivityCallbackHelper = new ActivityDataChangedHelper(m_Activity);
            m_ActivityCallbackHelper.PropertyChanged += new PropertyChangedEventHandler(OnActivityDataChanged);

            m_LapIndex = lapIndex;
            m_LapInfo = activityInfo.RecordedLapDetailInfo[m_LapIndex];
            m_ValidTimesDirty = true;
        }

        void OnActivityDataChanged(object sender, PropertyChangedEventArgs e)
        {
            if (e.PropertyName == "Activity.Duration")
            {
                m_ValidTimesDirty = true;
                TriggerValidTimesChanged();
            }
            else if (e.PropertyName == "LapInfo.Notes" && m_Activity != null)
            {
                ActivityInfo activityInfo = ActivityInfoCache.Instance.GetInfo(m_Activity);
                m_LapInfo = activityInfo.RecordedLapDetailInfo[m_LapIndex];
            }
        }

#region INamedZone Members

        public String Name
        {
            get
            {
                String lapName = String.Format(PluginView.GetLocalizedString("LapNumberText"), m_LapIndex + 1);

                if (m_LapInfo != null && m_LapInfo.Notes != String.Empty)
                {
                    lapName += " (" + m_LapInfo.Notes + ")";
                }

                return lapName;
            }
        }

        public IValueRangeSeries<DateTime> ValidTimes
        {
            get
            {
                UpdateValidTimes();

                return m_LapTime;
            }
        }

        public event PropertyChangedEventHandler ValidTimesChanged;

#endregion

        public override int GetHashCode()
        {
 	        return base.GetHashCode();
        }

        public override bool Equals(object obj)
        {
            RecordedLapNamedZone namedZone = obj as RecordedLapNamedZone;

            if (namedZone != null)
            {
                return namedZone.m_LapInfo.Equals(m_LapInfo);
            }

            return base.Equals(obj);
        }

        protected void TriggerValidTimesChanged()
        {
            if (ValidTimesChanged != null)
            {
                ValidTimesChanged(this, new PropertyChangedEventArgs("ValidTimes"));
            }
        }

        private void UpdateValidTimes()
        {
            if (m_ValidTimesDirty)
            {
                m_ValidTimesDirty = false;

                m_LapTime.Clear();
                m_LapTime.Add(new ValueRange<DateTime>(m_LapInfo.StartTime, m_LapInfo.EndTime));
            }
        }

        private IActivity m_Activity = null;
        private ActivityDataChangedHelper m_ActivityCallbackHelper = null;
        private LapDetailInfo m_LapInfo = null;
        private int m_LapIndex = -1;
        private IValueRangeSeries<DateTime> m_LapTime = new ValueRangeSeries<DateTime>();
        private bool m_ValidTimesDirty = false;
    }
}
